use_module(library(random)).
%jugar
%mostrarTablero(T)
%estadoFinal(T)
%ataque(T0, T1, F, C)
%barco(Fi,Ci,dir,tam).
%barco(2,0,h,3).
%barco(0,3,v,2).
%barco(0,0,h,2).


%C columna, E elemento o caracter a dibujar, L lista dibujada.
dibujarFila(0,_,[]):- !.
dibujarFila(C,E,L):- C1 is C-1, 
		   dibujarFila(C1,E,X),
		   append(X,[E],L).

%F filas, C columnas, T tablero a retornar.
tableroInicial(0,_,[]):- !.
tableroInicial(F, C, T) :- dibujarFila(C,a,LF), 
			   F1 is F-1, 
   			   tableroInicial(F1,C,X), 
			   append(X,[LF],T).

%P posicion, [H|R] lista a examinar.
%esta funcion indica si en la posicion dada por P, hay o no agua.
tieneElementoFila(0,[H|R],E) :- E=H, !.
tieneElementoFila(P,[H|R],E) :- P1 is P-1, 
		      		tieneElementoFila(P1,R,E).

%T0 tablero a examinar.
%esta funcion indica si en la posicion dada por (X,Y) hay o no el elemento especificado (a,f,g,h).
hayElemento(T0,X,Y,E) :-   obtenerSublista(T0, Y,Fila),
		           tieneElementoFila(X,Fila,E). 

%_[H|R] tablero, N numero de lista o fila a retornar, L lista o fila deseada.
%esta funcion obtiene la fila de un tablero especificada por N.
obtenerSublista([H|R], 0, L) :- L=H, !.
obtenerSublista([H|R], N, L) :- N1 is N-1,
			        obtenerSublista(R,N1,L).

%_[H|R] lista original, N numero de elementos, Lf lista final
%Esta funcion obtiene los primeros N elementos de la lista especificada por [H|R]. 
obtenerInicio(_,0,[]):- !.
obtenerInicio([H|R],N,Lf) :- 	X1 is N-1,
				obtenerInicio(R,X1,A),
				append([H],A,Lf).

%L lista original, N numero de elementos, Lf lista final
%Esta funcion obtiene los ultimos N elementos de la lista L. 
%Fume al estilo Novich
obtenerFin(L,N,Lf):- 	length(L,Tam),
			N > Tam,
			append([],[],Lf),!.
			
obtenerFin(L,N,Lf):-	length(L,Tam),
			N =< Tam,
			length(Lf,N), %se crea una lista de tam N, con cualquier cosa
			append(_,Lf,L),
			!. %Cuando se hace el append, necesariamente Lf va a tener los ultimos N elementos de la lista L.

%L lista inicial, P posicion, Edo o caracter a dibujar, Lf lista final.
%Esta funcion cambia en la lista L, especificamente en la posicion P, un caracter especificado por Edo.
cambiarEdo(L,P,Edo,Lf):-length(L,Tam), 
			obtenerInicio(L,P,A),
			append(A,[Edo],B),
			C1 is Tam-P-1,
			obtenerFin(L,C1,C),
			append(B,C,Lf).

mostrarTablero([]):-write(''),!.
mostrarTablero([H|R]):- mostrarElemento(H),nl,
			mostrarTablero(R).

mostrarElemento([]):- write(''),!.
mostrarElemento([H|R]):- write(H),
			 write(' '),
			 mostrarElemento(R).
%NO!
ataqueInicial(T0, T1, F, C):- 	N is F*C,
				random(1,N,X), %de posicion dentro de la lista
				random(1,F,Y), %de lista
				obtenerSublista(T0,Y,Sublist),
				not(tieneAgua(Sublist,X)),
				cambiarEdo(Sublist,X,Newsublist).

noHayAtaque([]) :- !.
noHayAtaque([H|R]) :- noHayAtaqueFila(H),
		    noHayAtaque(R).

noHayAtaqueFila([]) :- !.
noHayAtaqueFila([H|R]) :- H=a,
			noHayAtaqueFila(R).

%OJO quitar de la firma a X,Y,Z.
ataque(T0,T1,F,C,X,Y,Z) :- Y is random(F),
			   X is random(C),
			   Z is 1, %OJO QUITAR
		           ataque(T0,T1,F,C,X,Y),!.

ataque(T0,T1,F,C,X,Y):- %noHayAtaque(T0),
			hayBarco(X,Y),
			%Hay que verificar si el barco se hunde
			dibujarAtaque(T0,T1,F,C,X,Y,g),!.

ataque(T0,T1,F,C,X,Y):- %noHayAtaque(T0),
			hayElemento(T0,X,Y,a), %hayAGua
			dibujarAtaque(T0,T1,F,C,X,Y,f),!.

ataque(T0,T1,F,C,X,Y):- %noHayAtaque(T0),
			hayElemento(T0,X,Y,f), %hayFallo
			!.

ataque(T0,T1,F,C,X,Y):- noHayAtaque(T0),
			%hayElemento(T0,X,Y,g), %esta funcion debe verificar de que este hundido o golpeado el barco
			dibujarAtaque(T0,T1,F,C,X,Y,f),!.


dibujarAtaque(T0,T1,F,C,X,Y,E) :- E\=h,
				dibujarFila(C,a,Fila),
				cambiarEdo(Fila,X,E,Filacambiada),
				obtenerInicio(T0,Y,L1),
				append(L1,[Filacambiada],L2),
				length(L2,Tam),
				Aux is F-Tam,
				obtenerFin(T0,Aux,L3),
				append(L2,L3,T1),
				mostrarTablero(T1),!.

dibujarAtaque(T0,T1,F,C,X,Y,E) :- E=h,
				dibujarFila(C,a,Fila),
				cambiarEdo(Fila,X,E,Filacambiada),
				obtenerInicio(T0,Y,L1),
				append(L1,[Filacambiada],L2),
				length(L2,Tam),
				Aux is F-Tam,
				obtenerFin(T0,Aux,L3),
				append(L2,L3,T1),
				mostrarTablero(T1),!.

/*ataque(T0,T1,F,C,X,Y):- %not(noHayAtaque(T0)),
			hayBarco(X,Y),
			dibujarFila(C,a,Fila),
			cambiarEdo(Fila,X,f,Filacambiada),
			obtenerInicio(T0,Y,L1),
			append(L1,[Filacambiada],L2),
			length(L2,Tam),
			Aux is F-Tam,
			obtenerFin(T0,Aux,L3),
			append(L2,L3,T1),
			mostrarTablero(T1),!.*/

hayBarco(X,Y) :- barco(Y,X,_,_),!. 

hayBarco(X,Y):- barco(Y1,X,v,Tam),
		 Y\=Y1,
		 P is Y+Y1,
		 P<Tam,!.

hayBarco(X,Y):- barco(Y,X1,h,Tam),
		 X\=X1,
		 P is X+X1,
		 P<Tam,!.

		
% YO

esVOH(v).
esVOH(h).

cabeEnTablero(X0,Y0,v,T,X,Y):- Y1 is Y0+T, Y1 =< Y.
cabeEnTablero(X0,Y0,h,T,X,Y):- X1 is X0+T, X1 =< X.

solicitarDatosBarco(0,X,Y).
solicitarDatosBarco(N,X,Y):- write('Informacion de Barco:'),nl,
						     write('Tamano:'), read(T),
						     write('Direccion:'), read(D), esVOH(D),
                             write('Fila Inicial:'), read(Y0),
                             write('Columna Inicial:'), read(X0),
							 cabeEnTablero(X0,Y0,D,T,X,Y),
						     assert(barco(X0,Y0,D,T)),
						     N1 is N-1, solicitarDatosBarco(N1,X,Y),!.

pedirDatos(B,X,Y):- write('Num. de Filas:'), read(Y),
					write('Num. de Columnas:'), read(X),
					write('Cant. de Barcos:'), read(N),
					solicitarDatosBarco(N,X,Y),
					write('Cant. de proyectiles disponibles:'), read(B).
jugar:- pedirDatos(B,X,Y).





